// [[ OnflowGenerator File UUID: ea0e040f20974ea5b80118b0e204934b  ]]
package com.itdct.onflow.system.message.service

import com.alibaba.fastjson2.parseObject
import com.itdct.onflow.core.constant.CommonString
import com.itdct.onflow.core.constant.ReturnCode
import com.itdct.onflow.core.extend.*
import com.itdct.onflow.core.vo.KeyLabelValueVo
import com.itdct.onflow.core.vo.RespPageVo
import com.itdct.onflow.core.vo.RespVo
import com.itdct.onflow.system.account.constant.SysAccountRedisKey
import com.itdct.onflow.system.common.base.BaseSysService
import com.itdct.onflow.system.common.base.LoginDTO
import com.itdct.onflow.system.common.context.Context
import com.itdct.onflow.system.common.extend.dict
import com.itdct.onflow.system.common.websocket.SysWebSocketHandler
import com.itdct.onflow.system.message.entity.SysMessageEntity
import com.itdct.onflow.system.message.mapper.SysMessageMapper
import com.itdct.onflow.system.message.qo.SysMessageEditQo
import com.itdct.onflow.system.message.qo.SysMessageSearchQo
import com.itdct.onflow.system.message.vo.SysMessageDetailVo
import com.itdct.onflow.system.message.vo.SysMessageListVo
import com.itdct.onflow.system.message.vo.SysMessageNotReadCountVo
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * @author DCTANT
 * @date 2025-09-18 17:04:07
 * @version 1.0
 * @description 系统站内信服务
 */
@Service
class SysMessageService(
    val sysMessageMapper: SysMessageMapper,
    val sysWebSocketHandler: SysWebSocketHandler
) : BaseSysService() {

    @Transactional(rollbackFor = [Exception::class])
    fun add(qo: SysMessageEditQo, context: Context): RespVo<Long> {
        val addEntity = qo.toEntity(SysMessageEntity::class.java)
        val accountId = context.accountId ?: fail(ReturnCode.LACK_PARAM, CommonString.NEED_LOGIN)
        addEntity.sendUser = accountId
        addEntity.readState = false
        addEntity.systemSend = false
        val id = sysMessageMapper.insertEx(addEntity)

        if (onflowConfig.websocket.enable) {
            val redisKey = SysAccountRedisKey.LOGIN_ID(addEntity.receiveUser, "admin")
            val accountJsons = redisUtil.lGet(redisKey, 0, -1) as List<String>
            if (accountJsons.isNotEmpty()) {
                for (accountJson in accountJsons) {
                    val loginDto = accountJson.parseObject<LoginDTO>()
                    val hashMap = HashMap<String, Any>()
                    hashMap["message"] = addEntity.content
                    hashMap["title"] = addEntity.title
                    sysWebSocketHandler.sendToUser(loginDto.accountId, loginDto.token, hashMap)
                }
            }
        }
        return success(id)
    }

    @Transactional(rollbackFor = [Exception::class])
    fun update(qo: SysMessageEditQo, context: Context): RespVo<Unit> {
        val updateEntity = sysMessageMapper.selectByIdEx(qo.id)
        qo.injectValue(updateEntity)
        sysMessageMapper.updateEx(updateEntity)
        return success()
    }

    fun delete(qo: SysMessageEditQo, context: Context): RespVo<Unit> {
        val ids = qo.ids ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_DELETE_ID_LIST)
        val deleteEntities = sysMessageMapper.selectByIdsEx(ids)
        sysMessageMapper.deleteBatchEx(deleteEntities)
        return success()
    }

    fun detail(qo: SysMessageSearchQo, context: Context): RespVo<SysMessageDetailVo> {
        val id = qo.id ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_ID)
        val vo = sysMessageMapper.findById(id) ?: fail(CommonString.ENTITY_NOT_FOUND_USAGE("系统站内信", id))
        return success(vo.dict())
    }

    fun page(qo: SysMessageSearchQo, context: Context): RespPageVo<SysMessageListVo> {
        startPage(context)
        val pageData = sysMessageMapper.findByList(qo)
        return successPage(pageData.dict())
    }

    fun myPage(qo: SysMessageSearchQo, context: Context): RespPageVo<SysMessageListVo> {
        startPage(context)
        qo.receiveUser = context.accountId
        val pageData = sysMessageMapper.findByList(qo)
        return successPage(pageData.dict())
    }

    fun myAllRead(qo: SysMessageEditQo, context: Context): RespVo<Unit> {
        val accountId = context.accountId ?: fail(ReturnCode.LACK_PARAM, CommonString.NEED_LOGIN)
        sysMessageMapper.myAllRead(accountId)
        return success()
    }

    fun markRead(qo: SysMessageEditQo, context: Context): RespVo<Unit> {
        val accountId = context.accountId ?: fail(ReturnCode.LACK_PARAM, CommonString.NEED_LOGIN)
        val id = qo.id ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_ID)
        sysMessageMapper.myMarkRead(accountId, id)
        return success()
    }

    fun notReadCount(context: Context): RespVo<SysMessageNotReadCountVo> {
        val accountId = context.accountId ?: fail(ReturnCode.LACK_PARAM, CommonString.NEED_LOGIN)
        return success(sysMessageMapper.notReadCount(accountId, onflowConfig.platformType))
    }

// [[ OnflowGenerator Range (- selectFunctions -) Start ]]

    fun selectTitleList(qo: SysMessageSearchQo, context: Context): RespVo<List<KeyLabelValueVo>> {
        val vos = sysMessageMapper.selectTitleList(qo)
        return success(vos)
    }
// [[ OnflowGenerator Range (- selectFunctions -) End ]]
}